
#ifndef __REMOTE_SSH_KEY_FILE_H
#define __REMOTE_SSH_KEY_FILE_H

#include <vector>
#include "../aprtools/APRBucketBrigade.h"
#include "../aprtools/APRFuture.h"
#include "../db/NetworkDB.h"
#include "../db/KeyDB.h"
#include "SSHChannel.h"

/** A class that encapsulates a remote SSH public key file, usually
 * "~/.ssh/authorized_keys". */
class RemoteSSHKeyFile : public SSHChannel
{
   public:
      /** The type of IDs of different key purpose types. */
      enum sshkeytype    {   SSHKEY_RSA = 0,
                             SSHKEY_DSA = 1,
                             SSHKEY_ECDSA521 = 2,
                             SSHKEY_ECDSA384 = 3,
                             SSHKEY_ECDSA256 = 4,
                             SSHKEY_UNKNOWN = 5 };
      RemoteSSHKeyFile(SSHClient &itclient, NetworkDB &inetdb,
         KeyDB &ikeydb, const char *iourtag);
      ~RemoteSSHKeyFile();
      void reportAllKeys();
      int addKey(const char *keyname, const char *keypass);
      void cleanKeys();
   protected:
      char *getHomeDirectory();
      char *dumpFileData(const char *filename);
      void remoteKeySync(const char *keyfilename);
      int checkRemoteFileWritableOnly(const char *filename);
      int checkRemoteFileWritable(const char *filename);
      int tryLock(const char *lockdir, const char *lockname);
      int releaseMatchingLock(const char *lockdir, const char *lockname, int pidnum);
      void forceRemoveLockFile(const char *lockdir, const char *lockname);
      int commitKeyChanges(const char *keyfilename, const char *keytempdir, const char *keytempfile);
   private:
      char *getBase64Blob(const char *keyname, const char *keypass);
      int addKey_int(const char *keyname, const char *keypass);
      void importKeyFromLine(const char *keyfiledata, int beginidx, int endidx);
      /** The main store of SSH key type flags. */
      std::vector<sshkeytype> file_keytypes;
      /** Actual strings that correspond to the SSH key types. This is
       * included due to forward compatibility paranoia, so if the
       * program encounters key types it does not understand, horrors
       * do not break loose. */
      std::vector<char *> file_keytypetag;
      /** A vector of flags to specify whether each key is managed (by
       * us) or not. */
      std::vector<int> file_ismanaged;
      /** The key tag, which for managed keys does not include the tag
       * magic that specifically refers to our keys in particular. */
      std::vector<char *> file_keytag;
      /** The base 64 public key data included in each entry in the
       * file. */
      std::vector<char *> file_keybase64;
      /** The network database to look up and modify SSH host and
       * authentication key relationship details. */
      NetworkDB *netdb;
      /** The key database for looking up keys. */
      KeyDB *keydb;
      /** The tag which we use to reference our keys, which is removed
       * from loaded managed keys while in the class. */
      char *ourtag;
      /** The location of the remote SSH key file. */
      char *sshkeyfile;
      /** The PID used by the remote key file lock that is held by
       * this class.  For this reason this class should NEVER be
       * treated as persistent, because this lock has an expiry
       * time. */
      int lockpid;
      /** The memory pool used by this class. */
      apr_pool_t *mp;
};

#endif
